/*
 * @Author: WangLong
 * @Date: 2024-01-16 14:39:57
 * @LastEditTime: 2024-02-23 17:05:58
 * @LastEditors: MoWanPing
 * @Description:
 * @FilePath: \jnks_low_air_front_gov_online\src\utils\threesence.js
 */
import * as THREE from "three";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { DRACOLoader } from "three/examples/jsm/loaders/DRACOLoader";
import anime from "animejs/lib/anime.es.js";
import { whiteModelList } from "../../public/3dTiles/whiteModel/index";
import { MeshLine, MeshLineMaterial } from "three.meshline";
import { getModel } from '@/utils/indexeddb.js'
let renderer = null; // 渲染器
let renderer2 = null; // 渲染器
let camera = null; // 相机
let camera2 = null; // 相机
let scene = null; // 场景
let scene2 = null; // 场景
let customCoords = null; // 坐标转换器（经纬度转three位置）
let OpenPop = null; //弹窗方法
let cameraWidth = null;
let cameraHeight = null;
let spriteAll;
// let modelObject = [];
let modelObject = null;
let mapStatus = "SW";
let atmosphereGeometry = null;
// let particles = null;
let initmapID = null;

//演示
let routeLine = null; //演示线
let routeLine2 = null; //演示线
let routeLineDY = null; //演示线
let routeLineText = null; //演示线
let progress = 0; // 物体运动时在运动路径的初始位置，范围0~1
let progressText = 0; // 物体运动时在运动路径的初始位置，范围0~1
let velocity = 0.02; // 影响运动速率的一个值，范围0~1，需要和渲染频率结合计算才能得到真正的速率
let velocityText = 0.02; // 影响运动速率的一个值，范围0~1，需要和渲染频率结合计算才能得到真正的速率
let progress2 = 0; // 物体运动时在运动路径的初始位置，范围0~1
let progressText2 = 0; // 物体运动时在运动路径的初始位置，范围0~1
let velocity2 = 0.02; // 影响运动速率的一个值，范围0~1，需要和渲染频率结合计算才能得到真正的速率
let velocityText2 = 0.02; // 影响运动速率的一个值，范围0~1，需要和渲染频率结合计算才能得到真正的速率
// let velocity = 0.001; // 影响运动速率的一个值，范围0~1，需要和渲染频率结合计算才能得到真正的速率
let lineList = [];
let lineList2 = [];
let corrugatedCircle = null;
let corrugatedCircle2 = null;
let drawlLineArr = [];
let scanSetInterval = null;
//绘制墙体
let wallMat = null;
let wallMesh = null;
let animationList = [];
//雪 风 粒子效果
let particles = null;
let particleslist = [];
let isSingle = null
class Threesence {
  // 空域存储对象
  airspacePolygon = {};
  // 图标存储对象
  iconSaveObj = {};
  // 文字精灵图存储对象
  textSaveObj = {};
  aMap = null;
  constructor(aMap, openPop, width, height, single = false) {
    this.aMap = aMap;
    OpenPop = openPop;
    cameraWidth = width;
    cameraHeight = height;
    isSingle = single
  }

  initThree(mapCenter, mapID) {
    initmapID = mapID;
    customCoords = this.aMap.customCoords;
    // 数据使用转换工具进行转换，这个操作必须要提前执行（在获取镜头参数 函数之前执行），否则将会获得一个错误信息。
    customCoords.lngLatsToCoords(mapCenter);

    // 图标、管道实际操作图层
    let gllayer = new AMap.GLCustomLayer({
      zIndex: 130, // 图层的层级
      init: (gl) => {
        // camera = new THREE.PerspectiveCamera(
        //   60,
        //   window.innerWidth / window.innerHeight,
        //   100,
        //   1 << 30
        // );
        camera = new THREE.PerspectiveCamera(
          60,
          cameraWidth / cameraHeight,
          100,
          1 << 30
        );

        renderer = new THREE.WebGLRenderer({
          context: gl,
          alpha: true,
          antialias: true,
          canvas: gl.canvas,
        });

        renderer.autoClear = false;
        scene = new THREE.Scene();

        // 环境光照和平行光  目前没有模型不需要
        let aLight = new THREE.AmbientLight(0xffffff, 0.6);
        let dLight = new THREE.DirectionalLight(0xffffff, 0.3);
        dLight.position.set(1000, 1000, 900);
        scene.add(dLight);
        scene.add(aLight);
        //-------------------------------------------------------------------------
        setTimeout(() => {
          this.Update();
        }, 500);
        setTimeout(() => {
          if (isSingle) window.addEventListener("click", this.objOnMousemove, false);
          else window.addEventListener("dblclick", this.objOnMousemove, true);
        }, 1000);
        window.addEventListener("resize", function () {
          camera.aspect = cameraWidth / cameraHeight;
          camera.updateProjectionMatrix();
          renderer.setSize(window.innerWidth, window.innerHeight);
        })
      },

      render: () => {
        renderer.state.reset();
        // customCoords.setCenter([120.155125, 30.264725]);
        let { near, far, fov, up, lookAt, position } =
          customCoords.getCameraParams();
        camera.near = near;
        camera.far = far;
        camera.fov = fov;
        camera.position.set(...position);
        camera.up.set(...up);
        camera.lookAt(...lookAt);
        camera.updateProjectionMatrix();
        renderer.render(scene, camera);
      },
    });

    // 白膜图层
    let gllayer2 = new AMap.GLCustomLayer({
      zIndex: 2, // 图层的层级
      init: (gl) => {
        // camera2 = new THREE.PerspectiveCamera(
        //   60,
        //   window.innerWidth / window.innerHeight,
        //   100,
        //   1 << 30
        // );
        // camera2 = new THREE.PerspectiveCamera(60, 3840 / 1080, 100, 1 << 30);
        camera2 = new THREE.PerspectiveCamera(
          60,
          cameraWidth / cameraHeight,
          100,
          1 << 30
        );
        // camera2 = new THREE.PerspectiveCamera(
        //   30,
        //     window.innerWidth / window.innerHeight,
        //   100,
        //   1 << 30
        // );

        renderer2 = new THREE.WebGLRenderer({
          context: gl,
          alpha: true,
          antialias: true,
          canvas: gl.canvas,
        });

        renderer2.autoClear = false;
        scene2 = new THREE.Scene();

        this.getGltfModel();

        this.aMap.on("zoomchange", () => {
          var zoom = this.aMap.getZoom();
          if (mapStatus === "SW") {
            if (zoom >= 14.79) {
              if (modelObject) {
                modelObject.visible = false;
              }
            } else {
              if (modelObject) {
                modelObject.visible = true;
              }
            }
          }
        });

        if (window.innerWidth < 1920) {
          const touchDiv = document.getElementById(initmapID);
          window.addEventListener("pointerdown", this.objOnMousemove, false);
          touchDiv.addEventListener('touchmove', function(event) {
            modelObject.visible = false;
          });
          touchDiv.addEventListener('mousedown', function(event) {
            modelObject.visible = false;
          });
          touchDiv.addEventListener('mouseup', function(event) {
            modelObject.visible = true;
          });
          touchDiv.addEventListener('touchend', function(event) {
            modelObject.visible = true;
          });
        }

        // 环境光照和平行光  目前没有模型不需要
        let aLight = new THREE.AmbientLight(0xffffff, 0.6);
        let dLight = new THREE.DirectionalLight(0xffffff, 0.3);
        dLight.position.set(1000, 1000, 900);
        scene2.add(dLight);
        scene2.add(aLight);
        //-------------------------------------------------------------------------
        // setTimeout(() => {
        //   this.Update();
        // }, 500);
        // setTimeout(() => {
        //   window.addEventListener("click", this.objOnMousemove, false);
        // }, 1000);
      },

      render: () => {
        renderer2.state.reset();
        let { near, far, fov, up, lookAt, position } =
          customCoords.getCameraParams();
        camera2.near = near;
        camera2.far = far;
        camera2.fov = fov;
        camera2.position.set(...position);
        camera2.up.set(...up);
        camera2.lookAt(...lookAt);
        camera2.updateProjectionMatrix();
        renderer2.render(scene2, camera2);
      },
    });

    this.aMap.add(gllayer);
    this.aMap.add(gllayer2);
  }

  windowClick() {
    console.log("全局点击事件");
  }

  // 重新渲染Threejs
  handleResize(width, height, devicePixelRatio) {
    // 更新摄像头
    //aspect属性是设置摄像机视锥体的长宽比，通常是使用画布的宽/画布的高。
    camera.aspect = width / height;
    camera2.aspect = width / height;

    //   更新摄像机的投影矩阵
    //camera2.updateProjectionMatrix()用于更新摄像机投影矩阵，相机任何参数被改变以后必须被调用
    camera.updateProjectionMatrix();
    camera2.updateProjectionMatrix();

    //   更新渲染器
    renderer.setSize(width, height);
    renderer2.setSize(width, height);

    //   设置渲染器的像素比
    renderer.setPixelRatio(devicePixelRatio);
    renderer2.setPixelRatio(devicePixelRatio);
  }

  /**
   * @description:  导入白模
   */
  getGltfModel() {
    const loader = new GLTFLoader();
    let dracoLoader = new DRACOLoader();
    dracoLoader.setDecoderPath("/draco/");
    loader.setDRACOLoader(dracoLoader);
    console.log("模型地址", import.meta.env.VITE_BASE_PUBLICPATH + "/3dTiles/whiteModel/hangzhouNew3.gltf")
    let url = import.meta.env.VITE_BASE_PUBLICPATH + "/3dTiles/whiteModel/hangzhouNew3.gltf"
    getModel(url, 'hangzhou').then(blob => {
      let modelUrl = URL.createObjectURL(new Blob([blob]))
      loader.load(modelUrl, function (gltf) {
        let root = gltf.scene;
        console.log("已加载的模型", root)
        modelObject = root;
        // root.scale.set(-50,90,20) //设置模型大小
        root.rotation.x = Math.PI / 2; //以世界坐标y轴旋转180°
        root.position.set(2050, 8650, 0);
        root.translateX(-1999);
        gltf.scene.traverse(function (child) {
          // console.log(child);
          if (child.isMesh) {
            // console.log("进来了")
            child.material.depthWrite = false;
            // child.material.color.set(0x43dffe);
            child.material.color.set(0x0c7c9e);
            // //模型阴影
            // child.castShadow = true;
            // 调整金属度
            // child.material.metalness = 0.08;
            // //模型自发光
            // child.material.emissive = child.material.color;
            // child.material.emissiveMap = child.material.map;
          }
        });
        scene2.add(root); //模型加入场景中
      })
    })

    // loader.load(url, function (gltf) {
    //   let root = gltf.scene;
    //   console.log("已加载的模型", root)
    //   modelObject = root;
    //   // root.scale.set(-50,90,20) //设置模型大小
    //   root.rotation.x = Math.PI / 2; //以世界坐标y轴旋转180°
    //   root.position.set(2050, 8650, 0);
    //   root.translateX(-1999);
    //   gltf.scene.traverse(function (child) {
    //     // console.log(child);
    //     if (child.isMesh) {
    //       // console.log("进来了")
    //       child.material.depthWrite = false;
    //       // child.material.color.set(0x43dffe);
    //       child.material.color.set(0x0c7c9e);
    //       // //模型阴影
    //       // child.castShadow = true;
    //       // 调整金属度
    //       // child.material.metalness = 0.08;
    //       // //模型自发光
    //       // child.material.emissive = child.material.color;
    //       // child.material.emissiveMap = child.material.map;
    //     }
    //   });
    //   scene2.add(root); //模型加入场景中
    // });

    // whiteModelList.forEach((item, index) => {
    //   loader.load(item, function (gltf) {
    //     let root = gltf.scene;
    //     modelObject.push(root);
    //     // root.scale.set(-50,90,20) //设置模型大小
    //     root.rotation.x = Math.PI / 2; //以世界坐标y轴旋转180°
    //     root.position.set(2050, 8650, 0);
    //     root.translateX(-1999);
    //     gltf.scene.traverse(function (child) {
    //       // console.log(child);
    //       if (child.isMesh) {
    //         // console.log("进来了")
    //         child.material.depthWrite = false;
    //         child.material.color.set(0x9043dffe);
    //         // //模型阴影
    //         // child.castShadow = true;
    //         // 调整金属度
    //         // child.material.metalness = 0.08;
    //         // //模型自发光
    //         // child.material.emissive = child.material.color;
    //         // child.material.emissiveMap = child.material.map;
    //       }
    //     });
    //     root.visible = false;
    //     scene.add(root); //模型加入场景中
    //   });
    //   if (index === whiteModelList.length - 1) {
    //     setTimeout(() => {
    //       modelObject.forEach((item) => {
    //         item.visible = true;
    //       });
    //     }, 300);
    //   }
    // });

    // loader.load("/3dTiles/whiteModel/hangzhouNew2.gltf", function (gltf) {
    //   let root = gltf.scene;
    //   modelObject = root;
    //   // root.scale.set(-50,90,20) //设置模型大小
    //   root.rotation.x = Math.PI / 2; //以世界坐标y轴旋转180°
    //   root.position.set(2050, 8650, 0);
    //   root.translateX(-1999);
    //   // root.position.set(4925, -1465, 0)
    //   // root.translateX(-1999);
    //   // let material = new THREE.MeshBasicMaterial({
    //   //   color: 0x43E1FF
    //   //   // linewidth: 10
    //   // });
    //   gltf.scene.traverse(function (child) {
    //     // console.log(child);
    //     if (child.isMesh) {
    //       // console.log("进来了")
    //       child.material.depthWrite = false;
    //       child.material.color.set(0x9043dffe);
    //       // //模型阴影
    //       // child.castShadow = true;
    //       // 调整金属度
    //       // child.material.metalness = 0.08;
    //       // //模型自发光
    //       // child.material.emissive = child.material.color;
    //       // child.material.emissiveMap = child.material.map;
    //     }
    //   });
    //   scene.add(root); //模型加入场景中
    // });
  }

  /**
   * @description:  隐藏白模
   */
  closeModel(val) {
    modelObject.visible = false;
    mapStatus = val;
  }

  /**
   * @description:  三维地图显示白模
   */
  showModel(val) {
    modelObject.visible = true;
    mapStatus = val;
  }

  /**
   * @description: 鼠标悬浮事件
   */
  objOnMousemove(event) {
    // event.stopPropagation();
    // if (event.eventPhase === 3) return;
    let mouse = new THREE.Vector2();
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    // mouse.x = (event.clientX / (3840)) * 2 - 1;
    // mouse.y = -(event.clientY / (1080)) * 2 + 1;
    // 通过射线检测点击位置是否与精灵图相交
    const raycaster = new THREE.Raycaster();
    raycaster.setFromCamera(mouse, camera);
    let intersects = raycaster.intersectObjects(scene.children, true); //获取多个intersectObjects
    // let intersects = raycaster.intersectObject(scene);  //一对一intersectObject
    if (intersects.length <= 0 || intersects.length > 2) return;
    // scene.children
    //航线的点击事件
    let { typeName, typedata } = intersects[0].object;
    switch (typeName) {
      case "hangxian":
        OpenPop(typedata.airspaceApplyId, typedata.EntityType);
        break;
      case "kongyu":
        OpenPop(typedata.airspaceId, typedata.EntityType);
        break;
      case "aircraft":
        OpenPop(typedata.droneUK, typedata.EntityType);
        break;
      case "plane":
        OpenPop(typedata.droneUK, typedata.EntityType);
        break;
      case "firstLevel":
        OpenPop(typedata.alarmType, typedata.alarmLevel);
        break;
      case "secondLevel":
        OpenPop(typedata.alarmType, typedata.alarmLevel);
        break;
      // case "yanshi":
      //   YanshiviewLook(
      //     {
      //       flyApplyId: "dfc00412-a827-4cf8-be1f-942368c0b358",
      //       airspaceApplyId: "19db4a9f-e5be-4b2b-9967-c7cc9a48e7de",
      //       lowHeight: 50,
      //       topHeight: 150,
      //       flyApplyCode: "FX202401171158068023",
      //       applicant: "恒居科技有限公司",
      //       flyingHand: "夏祖伟 15956617515",
      //       aircraftId: "FK123",
      //       flightMode: 1,
      //       operatorMode: 1,
      //       startTime: "2024-01-17 00:00",
      //       endTime: "2024-01-31 00:00",
      //       taskNature: "其他",
      //       executionStatus: 3,
      //       contacts: null,
      //       mobile: null,
      //       focus: 1,
      //       droneUK: null,
      //       applyType: 1,
      //       deviceModel: "DJI Mavic 3 Pro",
      //       aircraftType: 0,
      //       tlowairServiceFiles: [
      //         {
      //           fileId: "9a0a4727-a9f0-4d54-a02e-b6067a45b7d4",
      //           createBy: "admin",
      //           createTime: "2024-01-17 11:57:19",
      //           updateBy: "",
      //           updateTime: null,
      //           remark: null,
      //           fileName: "测试_20231105171039A010",
      //           url: "http://101.71.158.60:50050/statics/2024/01/17/测试_20231105171039A010_20240117115625A001.pdf",
      //           businessId: "19db4a9f-e5be-4b2b-9967-c7cc9a48e7de",
      //           fileSize: 29,
      //           fileExtension: "pdf",
      //           status: 1,
      //         },
      //       ],
      //       flyingHandList: ["夏祖伟 15956617515"],
      //       aircraftIdList: ["FK123"],
      //       deviceModelList: ["DJI Mavic 3 Pro"],
      //       showSN: true,
      //     },
      //     true
      //   );
      //   break;
      default:
        break;
    }
    // OpenPop();
  }

  /**
   * @description: 绘制管道
   * @params radius  横截面的边长
   * @params linepath  管道路径
   * @params data  航线数据
   */
  pipeline(linepath, data, radius = 20) {
    let crossSection = [
      new THREE.Vector2(0, 0),
      new THREE.Vector2(radius, 0),
      new THREE.Vector2(radius, radius),
      new THREE.Vector2(0, radius),
      new THREE.Vector2(0, 0),
    ];
    // 2,创建形状模型
    // 2.1,创建点 横截面的数据
    var points = crossSection;
    // 2.2 创建形状轨迹
    var shape = new THREE.Shape(points);

    //数据处理高德坐标转换为three.js
    let pointline = [];
    linepath.forEach((element) => {
      let arr = customCoords
        .lngLatsToCoords([Number(element[0]), Number(element[1])])
        .flat();
      arr.push(element[2]);
      pointline.push(new THREE.Vector3(arr[0], arr[1], arr[2]));
    });

    var path = new THREE.CatmullRomCurve3(pointline);
    // 2.3 创建形状模型
    var extrudeSettings = {
      depth: 300,
      extrudePath: path,
      steps: 150,
      bevelEnabled: false,
      bevelThickness: 30,
    };
    var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);

    var material =
      // new THREE.MeshToonMaterial({
      //   color: 0xffff00,
      //   transparent: true,
      //   opacity: 1,
      //   side: THREE.DoubleSide, //双面可见
      //   depthWrite: false, //深度监测关闭
      // });
      new THREE.MeshPhongMaterial({
        color: 0x55aaff,
        emissive: 0xffff00,
      });
    // var material = new THREE.MeshBasicMaterial({
    //   color: 0x55aaff,
    //   wireframe: true,
    // }); //线框材质

    // var material = new THREE.MeshPhongMaterial({
    //   color: 0x0000ff,
    //   side: THREE.DoubleSide, //两面可见
    // }) //材质对象
    var mesh = new THREE.Mesh(geometry, material); //网格模型对象
    mesh.typeName = "hangxian";
    mesh.typedata = data;
    scene.add(mesh);
    return mesh;
  }

  /**
   * @description: 开启动画threejs实时更新地图
   * @return {*}
   */
  Update() {
    //three场景实时更新
    if (this.aMap) {
      this.aMap.render();
    }
    //根据浏览器刷新录适配three刷新频率
    requestAnimationFrame(() => {
      this.Update();
    });
  }

  /**
   * @description: 绘制精灵图icon
   * @params position [x,y,z]
   * @params imgurl  路径下的图片名称
   * @params data  数据内容
   * @params typeName  点击触发的事件类型
   * @params flag 标识：icon 图标，text 文本标识
   */
  iconSprite = (
    position,
    imgurl,
    data = {},
    typeName = "ICON",
    scaleX = 0.025,
    scaleY = 0.025
  ) => {
    if (window.innerWidth < 1920) {
      scaleX = 0.025;
      scaleY = 0.025;
    }
    // 2088x1920  ipad屏幕大小
    let textsprite;
    if (typeName === "kongyu") {
      this.removeIconSprite(data.airspaceId)
    }
    if (typeName === "plane") {
      this.removetextSprite(data.droneUK);
      //文字精灵图
      textsprite = this.createTag(position, data.droneSerialId);
    }
    if (typeName === "aircraft" || typeName === "plane") {
      this.removeIconSprite(data.id);
      if (data.type === 4) {
        this.removeIconSprite(data.id);
        // this.removetextSprite(data.droneUK);
        if (data.partnerId === 1 || data.partnerId === 8) {
          scaleX = 0.040;
          scaleY = 0.040;
        }else{
          // 其他通用行业无人机
          scaleX = 0.025;
          scaleY = 0.025;
        }
        //文字精灵图
        // textsprite = this.createTag(position, data.droneSerialId);
        // textsprite = this.createTag(position, "迅蚁", [0.027, 0.016, 0.004]);
      }
    }
    let arr = customCoords.lngLatsToCoords([position[0], position[1]]).flat();
    arr.push(position[2]);
    let [x, y, z] = arr;
    // 加载外部图片
    const img = new THREE.TextureLoader().load(import.meta.env.VITE_BASE_PUBLICPATH + "/img/cockpit/" + imgurl);
    // 创建精灵材质SpriteMaterial
    const spriteMaterial = new THREE.SpriteMaterial({
      map: img,
      rotation: data.type === 7 && data.directionAngle ? -data.directionAngle * (Math.PI / 180) : 0, //  Math.PI / 4旋转精灵对象45度，弧度值
      // rotation: 90 * (Math.PI / 180), //  Math.PI / 4旋转精灵对象45度，弧度值
      // color: 0x00ffff, //设置颜色
      sizeAttenuation: false, // false的话 不随着相机拉远而变小
      side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    });
    // 创建精灵模型，不需要几何体geometry参数
    const sprite = new THREE.Sprite(spriteMaterial);
    //设置精灵图的位置
    sprite.renderOrder = 999; // 设置renderOrder为999，确保它不被其他模型遮挡
    sprite.position.set(x, y, z);
    sprite.scale.set(scaleX, scaleY, 0.05); //只需要设置x、y两个分量就可以
    if (window.innerWidth < 1920 && typeName !== "plane") {
      sprite.center.set(0.5, -0.4);
    }
    // new THREE.Vector2(0.5, 0.5)
    // sprite.translateZ(20);
    // sprite.translateY(-10);
    //  自定义属性和数据
    sprite.typeName = typeName;
    sprite.typedata = data;
    sprite.IconId = data.id;
    if (typeName === "kongyu") {
      this.iconSaveObj[data.airspaceId] = sprite;
      // this.textSaveObj[data.airspaceId] = textsprite;
    }
    if (typeName === "plane") {
      this.textSaveObj[data.droneUK] = textsprite;
    }
    if (typeName === "aircraft" || typeName === "plane") {
      if (data.type === 4 && data.intrusionStatus !== 1) {
        this.textSaveObj[data.droneUK] = textsprite;
        this.iconSaveObj[data.id] = sprite;
      }else {
        this.iconSaveObj[data.id] = sprite;
      }
    }
    scene.add(sprite);
    return sprite;
  };

  /**
   * @description : 添加 精灵图 文字
   */
  createTag(position, name, size = [0.045, 0.02, 0.004]) {
    // console.log("添加文字");
    let arr = customCoords.lngLatsToCoords([position[0], position[1]]).flat();
    arr.push(position[2]);
    let [x, y, z] = arr;
    // console.log(x, y, z);
    //创建一个组对象
    // const group = new THREE.Group();
    const { spriteMaterial, p } = this.createCanvas(name);

    //精灵模型Sprite 矩形精灵模型与矩形网格模型的区别在于精灵模型的矩形平面会始终平行于Canvas画布 可以始终朝着正面
    const sprite = new THREE.Sprite(spriteMaterial);
    // sprite.scale.set(1 * p, 1, 1);
    //第一个参数可以调长度
    sprite.scale.set(size[0], size[1], size[2]);
    // if (window.innerWidth < 1920) {
    //   sprite.center.set(0.5, -1.35);
    // }else {
      sprite.center.set(0.5, -1); // 设置精灵对象的中心点偏移量
    // }
    //设置精灵图的位置
    sprite.position.set(x, y, z);
    // sprite.translateZ(1200);
    scene.add(sprite);
    //添加连接精灵图的线
    // var material = new LineMaterial({ color: 0xffffff, linewidth: 1 });
    // var geometry = new LineGeometry();
    // material.resolution.set(window.innerWidth, window.innerHeight);
    // var pointArr = [0, 0, 0, 0, 0, -2];
    // geometry.setPositions(pointArr);
    // // geometry.vertices.push(new THREE.Vector3(0, 0, 0))
    // // geometry.vertices.push(new THREE.Vector3(0, 0, -2))
    // var line = new Line2(geometry, material);
    // group.add(line);
    return sprite;
  }

  //用Canvas创建所需要的贴图
  createCanvas(name) {
    // const div = document.createElement("div");

    const canvas = document.createElement("canvas");

    // div.appendChild(canvas);
    // div.classList.add("flight-number");
    // div.style.borderRadius = "10px";
    const c = canvas.getContext("2d");
    const font = "Bold 100px Arial";
    const padding = 15;
    const h = 128;
    c.font = font;
    const w = c.measureText(name).width + 30;
    canvas.height = h;
    canvas.width = w;
    // 比例
    const p = w / h;
    c.fillStyle = "rgba(55,55,55,0.6)";
    c.fillRect(0, 0, w, h);
    c.beginPath();
    c.translate(padding, h / 2);
    c.font = font;
    c.textBaseline = "middle";
    c.fillStyle = "#fff";
    c.fillText(name, 0, 2);
    // c.fillText('GDP: 50000亿元', -15, 55)
    // canvas画布对象作为CanvasTexture的参数重建一个纹理对象
    // canvas画布可以理解为一张图片
    const texture = new THREE.CanvasTexture(canvas);
    return {
      spriteMaterial: new THREE.SpriteMaterial({
        map: texture,
        sizeAttenuation: false, // false的话 不随着相机拉远而变小
        transparent: true,
        side: THREE.DoubleSide,
      }),
      p,
    };
  }

  /**
   * @description : 清除图标
   */
  removeIconSprite = (id) => {
    if (this.iconSaveObj[id]) {
      scene.remove(this.iconSaveObj[id]);
      delete this.iconSaveObj[id];
    }
  };

  /**
   * @description : 清除文字图标
   */
  removetextSprite = (id) => {
    if (this.textSaveObj[id]) {
      scene.remove(this.textSaveObj[id]);
      delete this.textSaveObj[id];
    }
  };

  /**
   * @description: 绘制一条虚线
   * params dashedlinepath //两个点数据
   */
  dashedline = (dashedlinepath) => {
    let dashed = [];
    let lineGeometry = new THREE.Geometry(); //生成几何体
    dashedlinepath.forEach((element) => {
      let arr = customCoords
        .lngLatsToCoords([Number(element[0]), Number(element[1])])
        .flat();
      arr.push(element[2]);
      lineGeometry.vertices.push(new THREE.Vector3(arr[0], arr[1], arr[2]));
    });
    // lineGeometry.vertices.push(dashed[0]); //线段的两个顶点
    // lineGeometry.vertices.push(dashed[1]);

    let line = new THREE.Line(
      lineGeometry,
      new THREE.LineDashedMaterial({
        color: 0xffff30, //线段的颜色
        dashSize: 10, //短划线的大小
        gapSize: 3, //短划线之间的距离
      })
    );
    line.computeLineDistances(); //不可或缺的，若无，则线段不能显示为虚线
    scene.add(line);
    return line;
  };

  /**
   * @description:绘制轨迹
   */
  trajectory(
    list = [
      [120.052293, 30.283996, 100],
      [120.108598, 30.268875, 100],
      [120.13778, 30.27184, 100],
      [120.083535, 30.224981, 100],
      [120.038903, 30.232842, 100],
    ],
    index = 1
  ) {
    var geometry = new THREE.Geometry();

    //材质
    var material = null;
    if (index == 1) {
      //轨迹的材质
      material = new THREE.LineBasicMaterial({
        color: 0xff0000,
        linewidth: 5,
        linecap: "round",
        linejoin: "round",
      });
    } else {
      //虚线材质
      material = new THREE.LineDashedMaterial({
        color: 0x909399,
        linewidth: 1,
        scale: 1,
        dashSize: 3,
        gapSize: 5,
      });
    }
    var color1 = new THREE.Color(0x444444),
      color2 = new THREE.Color(0xff0000);

    list.forEach((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      var p1 = new THREE.Vector3(point[0], point[1], item[2]);
      geometry.vertices.push(p1);
      geometry.colors.push(color1);
      geometry.colors.push(color2);
    });
    routeLineDY = new THREE.Line(geometry, material, THREE.LineSegments);
    if (index == 2) {
      routeLineDY.computeLineDistances();
    }
    scene.add(routeLineDY);
    drawlLineArr.push(routeLineDY);
  }

  /**
   * @description: 删除轨迹
   */
  clearRemovedrawlLine = () => {
    console.log("drawlLineArr", drawlLineArr)
    if (drawlLineArr.length > 0) {
      drawlLineArr.forEach((it) => {
        scene.remove(it);
      });
      progress = 0;
      drawlLineArr = [];
      lineList = [];
      lineList2 = [];
      progress2 = 0;
      velocity = 0.02;
      velocity2 = 0.02;
      if (scanSetInterval) {
        clearInterval(scanSetInterval);
      }
    }
  };
  /**
   * @description:绘制轨迹曲线
   */
  curvetrajectory(
    cubeList = [
      [120.052293, 30.283996, 100],
      [120.108598, 30.268875, 100],
      [120.13778, 30.27184, 100],
      [120.083535, 30.224981, 100],
      [120.038903, 30.232842, 100],
      [120.034903, 30.239842, 400],
    ]
  ) {
    let list = [];
    cubeList.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线
    routeLine = new THREE.CatmullRomCurve3(list);
    routeLine.curveType = "catmullrom"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine.tension = 0; //设置线的张力，0为无弧度折线
    routeLine.closed = false; // 曲线是否闭合

    // const points = curve.getPoints(50); // 50等分获取曲线点数组
    // const line = new THREE.LineLoop(
    //   new THREE.BufferGeometry().setFromPoints(points),
    //   new THREE.LineBasicMaterial({ color: 0xff0000 })
    // ); // 绘制实体线条，仅用于示意曲线，后面的向量线条同理，相关代码就省略了

    // //曲线上获取点
    // const pointsArr = routeLine.getPoints(100);
    // const geometry = new THREE.BufferGeometry();
    // //读取坐标数据赋值给几何体顶点
    // geometry.setFromPoints(pointsArr);
    // // 线材质
    // const material = new THREE.LineBasicMaterial({
    //   color: 0x00fffff,
    // });
    // // 线模型
    // const line = new THREE.Line(geometry, material);

    // scene.add(line);
    return routeLine;
  }

  curvetrajectory2(
    cubeList = [
      [120.052293, 30.283996, 100],
      [120.108598, 30.268875, 100],
      [120.13778, 30.27184, 100],
      [120.083535, 30.224981, 100],
      [120.038903, 30.232842, 100],
      [120.034903, 30.239842, 400],
    ]
  ) {
    let list = [];
    cubeList.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线
    routeLine2 = new THREE.CatmullRomCurve3(list);
    routeLine2.curveType = "catmullrom"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine2.tension = 0; //设置线的张力，0为无弧度折线
    routeLine2.closed = false; // 曲线是否闭合

    // const points = curve.getPoints(50); // 50等分获取曲线点数组
    // const line = new THREE.LineLoop(
    //   new THREE.BufferGeometry().setFromPoints(points),
    //   new THREE.LineBasicMaterial({ color: 0xff0000 })
    // ); // 绘制实体线条，仅用于示意曲线，后面的向量线条同理，相关代码就省略了

    // //曲线上获取点
    // const pointsArr = routeLine.getPoints(100);
    // const geometry = new THREE.BufferGeometry();
    // //读取坐标数据赋值给几何体顶点
    // geometry.setFromPoints(pointsArr);
    // // 线材质
    // const material = new THREE.LineBasicMaterial({
    //   color: 0x00fffff,
    // });
    // // 线模型
    // const line = new THREE.Line(geometry, material);

    // scene.add(line);
    return routeLine2;
  }

  changePosition(t) {
    const position = curve.getPointAt(t); // t: 当前点在线条上的位置百分比，后面计算
    mesh.position.copy(position);
  }

  changeLookAt(t) {
    const tangent = curve.getTangentAt(t);
    const lookAtVec = tangent.add(position); // 位置向量和切线向量相加即为所需朝向的点向量
    mesh.lookAt(lookAtVec);
  }

  /**
   * @description:绘制无人机图标
   * @params position 位置
   * @params iocn 图标
   * @params flag 标识：icon 图标，text 文本标识
   */
  flyicon(position, iocn, positionList = [0.03, 0.03], typeName = "ICON") {
    // 119.924749, 30.232693
    let imgicon = this.iconSprite(
      position,
      iocn,
      {},
      typeName,
      positionList[0],
      positionList[1]
    );
    return imgicon;
  }

  /**
   * @description:绘制圆形管道
   */
  circular() {
    /**Three]s创建一条管道**/
    //创建多段线条的顶点数据
    var p1 = new THREE.Vector3(-85.35, -35.36, 1000);
    var p2 = new THREE.Vector3(-50, 20, 1000);
    var p3 = new THREE.Vector3(0, 50, 1000);
    var p4 = new THREE.Vector3(50, 0, 1000);
    var p5 = new THREE.Vector3(85.35, -35.36, 1000);

    /**创建线条一：直线**/
    let line1 = new THREE.LineCurve3(p1, p2);
    //重建线条2：三维样条曲线
    var curve = new THREE.CatmullRomCurve3([p2, p3, p4]);
    /**创建线条3：直线**/
    let line2 = new THREE.LineCurve3(p4, p5);
    var CurvePath = new THREE.CurvePath(); //创建CurvePath对象 曲线路径
    CurvePath.curves.push(line1, curve, line2); //插入多段线条
    //通过多段曲线路径创建生成管道
    //通过多段曲线路径创建生成管道，CCurvePath:管道路径 第三个参数设置半径
    var geometry1 = new THREE.TubeGeometry(CurvePath, 100, 30, 25, false); //true 是管道闭和

    var material1 = new THREE.MeshToonMaterial({
      color: 0x00ff00,
      transparent: true,
      opacity: 0.6,
      side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    }); //材质对象Material
    // new THREE.MeshToonMaterial({
    //   color: 0x2defff,
    //   transparent: true,
    //   opacity: 1,
    //   side: THREE.DoubleSide, //双面可见
    //   depthWrite: false, //深度监测关闭
    // });
    var mesh1 = new THREE.Mesh(geometry1, material1); //网格模型灯家mesh
    scene.add(mesh1); //网格模型添加到场景中
  }

  /**
   * @description:绘制曲线圆形管道
   */
  circular1(
    arr = [
      [120.0717640415461, 30.185688130425536],
      [120.17580074284429, 30.220185941065505],
    ],
    color = "#23f155"
  ) {
    let CatmullRomCurve3List = [];
    arr.forEach((item, index) => {
      CatmullRomCurve3List.push(
        new THREE.Vector3(
          customCoords.lngLatToCoord(item)[0],
          customCoords.lngLatToCoord(item)[1],
          1000
        )
      );
    });
    /**Three]s创建一条管道**/
    //创建多段线条的顶点数据
    // var p1 = new THREE.Vector3(-85.35, -35.36, 1000);
    // var p2 = new THREE.Vector3(-50, 20, 1000);

    /**创建线条一：直线**/
    // let line1 = new THREE.LineCurve3(p1, p2);
    var curve = new THREE.CatmullRomCurve3(CatmullRomCurve3List);
    var CurvePath = new THREE.CurvePath(); //创建CurvePath对象 曲线路径
    CurvePath.curves.push(curve); //插入多段线条
    //通过多段曲线路径创建生成管道
    //通过多段曲线路径创建生成管道，CCurvePath:管道路径 第三个参数设置半径
    var geometry1 = new THREE.TubeGeometry(CurvePath, 150, 80, 25, false); //true 是管道闭和

    var material1 = new THREE.MeshToonMaterial({
      color,
      transparent: true,
      opacity: 0.4,
      side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    }); //材质对象Material
    // new THREE.MeshToonMaterial({
    //   color: 0x2defff,
    //   transparent: true,
    //   opacity: 1,
    //   side: THREE.DoubleSide, //双面可见
    //   depthWrite: false, //深度监测关闭
    // });
    var mesh1 = new THREE.Mesh(geometry1, material1); //网格模型灯家mesh
    scene.add(mesh1); //网格模型添加到场景中
    return mesh1;
  }

  /**
   * @description:绘制扩散波
   * @params multiple 光圈大小变换倍数
   */
  diffusionwave(multiple = 2.5, color = 0xffff00, position = [120.29582977, 30.18668309]) {
    let geometry = new THREE.PlaneBufferGeometry(multiple * 1000, multiple * 1000); //默认在XOY平面上
    let textureLoader = new THREE.TextureLoader(); // TextureLoader创建一个纹理加载器对象
    let material = new THREE.MeshBasicMaterial({
      color,
      map: textureLoader.load(import.meta.env.VITE_BASE_PUBLICPATH + "/img/cockpit/circle.png"),
      transparent: true, //使用背景透明的png贴图，注意开启透明计算
      // side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    });
    corrugatedCircle = new THREE.Mesh(geometry, material);
    // mesh.rotateX(-Math.PI / 2); //旋转到XOZ平面
    // let [p1, p2] = customCoords.lngLatToCoord(position);
    let [p1, p2] = customCoords.lngLatToCoord(position);
    corrugatedCircle.position.set(p1, p2, 100);
    scene.add(corrugatedCircle);
    drawlLineArr.push(corrugatedCircle);
    // 光圈大小在1~2.5倍之间变化
    let _s = multiple;
    scanSetInterval = setInterval(() => {
      _s += 0.1;
      corrugatedCircle.scale.set(_s, _s, _s);
      if (_s <= 1.5) {
        corrugatedCircle.material.opacity = (_s - 1.0) * 1.8; //3.3约等于1/(1.3-1.0)，保证透明度在0~1之间变化
      } else if (_s > 1.5 && _s <= multiple) {
        corrugatedCircle.material.opacity = 1.4 - _s / multiple; //缩放2.5对应0 缩放1.0对应1
      } else {
        _s = 1.0;
      }
      // renderer.render(scene, camera); //执行渲染操作
    }, 300);
    return corrugatedCircle;
  }

  /**
   * @description:绘制第二个扩散波
   * @params multiple 光圈大小变换倍数
   */
  diffusionwave2(multiple = 2.5, color = 0xffff00, position) {
    let geometry = new THREE.PlaneBufferGeometry(multiple * 1000, multiple * 1000); //默认在XOY平面上
    let textureLoader = new THREE.TextureLoader(); // TextureLoader创建一个纹理加载器对象
    let material = new THREE.MeshBasicMaterial({
      color,
      map: textureLoader.load(import.meta.env.VITE_BASE_PUBLICPATH + "/img/cockpit/circle.png"),
      transparent: true, //使用背景透明的png贴图，注意开启透明计算
      // side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    });
    corrugatedCircle2 = new THREE.Mesh(geometry, material);
    // mesh.rotateX(-Math.PI / 2); //旋转到XOZ平面
    // let [p1, p2] = customCoords.lngLatToCoord(position);
    let [p1, p2] = customCoords.lngLatToCoord(position);
    corrugatedCircle2.position.set(p1, p2, 100);
    scene.add(corrugatedCircle2);
    drawlLineArr.push(corrugatedCircle2);
    // 光圈大小在1~2.5倍之间变化
    let _s = multiple;
    scanSetInterval = setInterval(() => {
      _s += 0.1;
      corrugatedCircle.scale.set(_s, _s, _s);
      if (_s <= 1.5) {
        corrugatedCircle.material.opacity = (_s - 1.0) * 1.8; //3.3约等于1/(1.3-1.0)，保证透明度在0~1之间变化
      } else if (_s > 1.5 && _s <= multiple) {
        corrugatedCircle.material.opacity = 1 - _s / multiple; //缩放2.5对应0 缩放1.0对应1
      } else {
        _s = 1.0;
      }
      // renderer.render(scene, camera); //执行渲染操作
    }, 300);
  }

  /**
   * @修改第二个光波位置
   * */
  setSecondWave(position) {
    let arr = customCoords.lngLatsToCoords([position[0], position[1]]).flat();
    arr.push(position[2]);
    let [x, y, z] = arr;
    corrugatedCircle2.position.set(x, y, z);
  }

  /**
   * @description:物体沿线移动方法
   * @params icon 物体 精灵图
   * @params flag 标识：icon 图标，text 文本标识
   */
  moveOnCurve(icon, color, waveMove = false, secondWave = false, name) {
    let HeightLimitGeometry = null;
    if (routeLine == null || icon == null) {
      // console.log("Loading");
      return;
    } else {
      if (progress <= 1 - velocity) {
        const point = routeLine.getPointAt(progress); //获取 曲线指定点坐标   获取曲线当前点
        const pointBox = routeLine.getPointAt(progress + velocity); //获取曲线指定点坐标  获取下一个点
        if (point && pointBox) {
          //存储取的两个点 用于绘制轨迹线段
          lineList.push([point.x, point.y, point.z]);
          //更新图标位置
          icon.position.set(point.x, point.y, point.z);
          // // 计算朝向(未生效)
          // var direction = new THREE.Vector3(point.x, point.y, point.z).normalize();
          // var angle = Math.atan2(direction.y, direction.x);
          // icon.rotation.z = angle; // 旋转精灵图
          // model.lookAt(pointBox.x, pointBox.y, pointBox.z);//因为这个模型加载进来默认面部是正对Z轴负方向的，所以直接lookAt会导致出现倒着跑的现象，这里用重新设置朝向的方法来解决。
          //必须两个点才可以画出线
          if (lineList.length > 2) {
            this.drawLine2(
              [lineList[lineList.length - 2], lineList[lineList.length - 1]],
              color,
              name
            );
            // 更新波纹圆位置
            if (waveMove && corrugatedCircle) {
              corrugatedCircle.position.set(point.x, point.y, point.z);
            }
            // 更新波纹圆位置
            if (secondWave && corrugatedCircle2) {
              corrugatedCircle2.position.set(point.x, point.y, point.z);
            }
          }
          // 视角跟随
          if (progress > 0.1) {
            // var pos = this.curve.getPointAt(this.progress - 0.1);
            // this.camera.position.copy(pos);
            camera.lookAt(point);
          }

          // var targetPos = pointBox; //目标位置点
          // var offsetAngle = 0; //目标移动时的朝向偏移

          // //以下代码在多段路径时可重复执行
          // var mtx = new THREE.Matrix4(); //创建一个4维矩阵
          // // .lookAt ( eye : Vector3, target : Vector3, up : Vector3 ) : this,构造一个旋转矩阵，从eye 指向 target，由向量 up 定向。
          // mtx.lookAt(icon.position, targetPos, icon.up); //设置朝向
          // mtx.multiply(
          //   new THREE.Matrix4().makeRotationFromEuler(
          //     new THREE.Euler(0, offsetAngle, 0)
          //   )
          // );
          // var toRot = new THREE.Quaternion().setFromRotationMatrix(mtx); //计算出需要进行旋转的四元数值
          // icon.quaternion.slerp(toRot, 0.2);
        }

        progress += velocity;
      } else {
        progress = 0;
        // console.log("停止");
        // console.log("---flag");
        // console.log(flag);
        routeLine = null;
        // let endLine = lineList[lineList.length - 1];
        // lineList = [];
        // lineList.push(endLine);
        if (secondWave) this.remove(corrugatedCircle2)
        return "stop";
      }
    }
  }
  moveOnCurve2(icon, color, waveMove = false, secondWave = false, name) {
    let HeightLimitGeometry = null;
    if (routeLine2 == null || icon == null) {
      // console.log("Loading");
      return;
    } else {
      if (progress2 <= 1 - velocity2) {
        const point = routeLine2.getPointAt(progress2); //获取 曲线指定点坐标   获取曲线当前点
        const pointBox = routeLine2.getPointAt(progress2 + velocity2); //获取曲线指定点坐标  获取下一个点

        if (point && pointBox) {
          //存储取的两个点 用于绘制轨迹线段
          lineList.push([point.x, point.y, point.z]);
          //更新图标位置
          icon.position.set(point.x, point.y, point.z);
          // model.lookAt(pointBox.x, pointBox.y, pointBox.z);//因为这个模型加载进来默认面部是正对Z轴负方向的，所以直接lookAt会导致出现倒着跑的现象，这里用重新设置朝向的方法来解决。
          //必须两个点才可以画出线
          if (lineList.length > 2) {
            this.drawLine2(
              [lineList[lineList.length - 2], lineList[lineList.length - 1]],
              color,
              name
            );
            // 更新波纹圆位置
            if (waveMove && corrugatedCircle) {
              corrugatedCircle.position.set(point.x, point.y, point.z);
            }
            // 更新波纹圆位置
            if (secondWave && corrugatedCircle2) {
              corrugatedCircle2.position.set(point.x, point.y, point.z);
            }
          }
          // 视角跟随
          if (progress2 > 0.1) {
            // var pos = this.curve.getPointAt(this.progress2 - 0.1);
            // this.camera.position.copy(pos);
            camera.lookAt(point);
          }

          // var targetPos = pointBox; //目标位置点
          // var offsetAngle = 0; //目标移动时的朝向偏移

          // //以下代码在多段路径时可重复执行
          // var mtx = new THREE.Matrix4(); //创建一个4维矩阵
          // // .lookAt ( eye : Vector3, target : Vector3, up : Vector3 ) : this,构造一个旋转矩阵，从eye 指向 target，由向量 up 定向。
          // mtx.lookAt(icon.position, targetPos, icon.up); //设置朝向
          // mtx.multiply(
          //   new THREE.Matrix4().makeRotationFromEuler(
          //     new THREE.Euler(0, offsetAngle, 0)
          //   )
          // );
          // var toRot = new THREE.Quaternion().setFromRotationMatrix(mtx); //计算出需要进行旋转的四元数值
          // icon.quaternion.slerp(toRot, 0.2);
        }

        progress2 += velocity;
      } else {
        progress2 = 0;
        // console.log("停止");
        // console.log("---flag");
        // console.log(flag);
        routeLine2 = null;
        // let endLine = lineList[lineList.length - 1];
        // lineList = [];
        // lineList.push(endLine);
        if (secondWave) this.remove(corrugatedCircle2)
        return "stop";
      }
    }
  }

  drawLine2(list, color = "#ce2c29", name) {
    let pointsArr = [];
    list.forEach((item) => {
      pointsArr.push(item[0]);
      pointsArr.push(item[1]);
      pointsArr.push(item[2]);
    });

    // 初始化MeshLine
    const line = new MeshLine();
    // 传入顶点坐标数据
    line.setPoints(pointsArr);
    //轨迹的材质
    let material = new MeshLineMaterial({
      useMap: 0,
      color: color,
      opacity: name !== undefined ? 0 : 1,
      resolution: new THREE.Vector2(window.innerWidth, window.innerHeight),
      sizeAttenuation: 0, //线的大小是否会受相机影响。(0 - 不会, 1 - 会)
      lineWidth: 6,
      transparent: true,
      wireframe: false,
      // side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    });
    let mesh = new THREE.Mesh(line.geometry, material);
    mesh.layers.enable(1);
    scene.add(mesh);
    drawlLineArr.push(mesh);
    //----------------------------------------------------
    // var geometry = new THREE.Geometry();

    // //材质
    // var material = null;
    // //轨迹的材质
    // material = new THREE.LineBasicMaterial({
    //   color: color,
    //   linewidth: 100,
    //   linecap: "round",
    //   linejoin: "round",
    //   // side: THREE.DoubleSide, //双面可见
    //   depthWrite: false, //深度监测关闭
    // });

    // var color1 = new THREE.Color(0x444444),
    //   color2 = new THREE.Color(0xff0000);

    // list.forEach((item) => {
    //   var p1 = new THREE.Vector3();
    //   p1.x = item[0];
    //   p1.y = item[1];
    //   p1.z = item[2];
    //   // console.log("v3", p1);
    //   // var p1 = new THREE.Vector3(point[0], point[1], item[2]);
    //   geometry.vertices.push(p1);
    //   geometry.colors.push(color1);
    //   geometry.colors.push(color2);
    // });
    // let line = new THREE.Line(geometry, material, THREE.LineSegments);
    // line.renderOrder = 998; // 设置renderOrder为999，确保它不被其他模型遮挡
    // scene.add(line);
    // drawlLineArr.push(line);
  }

  // /**
  //  * @description: 绘制标注点
  //  */
  // iconPoint() {
  //   console.log("zhixing");
  //   let posArr = [
  //     { id: 1, name: "杭州市", lng: "120.155125", lat: "30.264725" },
  //     // { id: 2, name: "绍兴市", lng: "120.582886", lat: "30.051549" },
  //     // { id: 3, name: "金华市", lng: "119.647265", lat: "29.079195" },
  //     // { id: 4, name: "温州市", lng: "120.699279", lat: "27.993849" },
  //     // { id: 5, name: "宁波市", lng: "121.62454", lat: "29.860258" },
  //     // { id: 6, name: "兰州市", lng: "103.834170", lat: "36.061380" },
  //     // { id: 7, name: "长春市", lng: "125.324501", lat: "43.886841" },
  //     // { id: 8, name: "济南市", lng: "117.000923", lat: "36.675808" },
  //     // { id: 9, name: "银川市", lng: "106.230977", lat: "38.487783" },
  //     // { id: 10, name: "海南市", lng: "109.614267", lat: "18.309443" },
  //     // { id: 11, name: "乌鲁木齐市", lng: "87.616824", lat: "43.825377" },
  //   ]; // 设备数据
  //   posArr.forEach((item) => {
  //     let cityXyz = customCoords.lngLatToCoord([item.lng, item.lat]);
  //     console.log(cityXyz);
  //     let cityGeometry = new THREE.PlaneGeometry(100, 100);
  //     let textureLoader = new THREE.TextureLoader(); // TextureLoader创建一个纹理加载器对象

  //     let texture = textureLoader.load("/img/cockpit/flyHandH.png");
  //     let cityWaveMaterial = new THREE.MeshBasicMaterial({
  //       color: 0xff0000,
  //       map: texture,
  //       transparent: true, //使用背景透明的png贴图，注意开启透明计算
  //       opacity: 1,
  //       depthWrite: false, //禁止写入深度缓冲区数据
  //     });

  //     let cityWaveMesh = new THREE.Mesh(cityGeometry, cityWaveMaterial);
  //     cityWaveMesh.position.set(cityXyz[0], cityXyz[1], 1000);
  //     scene.add(cityWaveMesh);
  //   });
  // }

  /**
   * @description : 添加航线
   */
  drawLine1(data) {
    let startPoint = null; // 起点
    let endPoint = null; // 终点
    let standbyPoint = null; // 备降点
    let standbyLine = null; // 备降点的线
    let line = null; // 航线
    //绘制所有的航线
    if (data.EntityType === "applyline") line = this.dashedline(data.position);
    else line = this.pipeline(data.position, data);
    startPoint = this.iconSprite(
      data.takeoffPoint,
      "startPoint.png",
      data,
      "hangxian",
      0.025,
      0.03
    );
    endPoint = this.iconSprite(
      data.landingPoint,
      "endPoint.png",
      data,
      "hangxian",
      0.025,
      0.03
    );
    //没有备降点不执行画线
    if (data.standbyPosition) {
      standbyLine = this.dashedline(data.standbyPosition);
      standbyPoint = this.iconSprite(
        data.standbyPoint,
        "standbyPoint.png",
        data,
        "hangxian",
        0.025,
        0.03
      );
    }
    return { line, endPoint, startPoint, standbyPoint, standbyLine };
  }

  /**
   * @description : 清除航线
   */
  removeLineList(lineArr) {
    if (lineArr.length < 1) return;
    lineArr.forEach((item) => {
      scene.remove(item);
    });
  }

  /**
   * @description : 清除无人机轨迹
   */
  removeLineList2() {
    lineList = [];
    progress = 0;
  }

  /**
   * @description : 回显圆柱
   * @params position 圆柱中心坐标
   * @params radius  圆柱半径
   * @params topHeight 顶高
   * @params clolor  颜色
   * @params data  圆柱数据信息
   * @params meshheight  圆柱的高度
   */
  CysGeometry = (
    positions,
    radius,
    topHeight,
    clolor,
    data,
    meshheight = 0
  ) => {
    let position = customCoords.lngLatToCoord(positions);
    const geometry = new THREE.CylinderGeometry(radius, radius, topHeight, 320);
    const material = new THREE.MeshToonMaterial({
      // color: 0x2defff,
      color: clolor,
      transparent: true,
      opacity: 0.5,
      side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
      depthTest: true,
    });
    const cylinder = new THREE.Mesh(geometry, material);
    cylinder.rotation.x = Math.PI / 2;
    cylinder.position.set(position[0], position[1], meshheight);
    let pointLight = new THREE.PointLight(0xffffff, 1, radius);
    pointLight.position.set(position[0], position[1], 4000);
    // scene.add(pointLight);
    cylinder.typeName = "kongyu";
    cylinder.typedata = data;
    scene.add(cylinder);
    if (this.airspacePolygon[data.airTypeId])
      this.airspacePolygon[data.airTypeId].push(cylinder);
    else this.airspacePolygon[data.airTypeId] = [cylinder];
    return cylinder;
  };

  /**
   * @description : 回显防御圈
   * @params position 圆柱中心坐标
   * @params radius  圆柱半径
   * @params topHeight 顶高
   * @params clolor  颜色
   * @params data  圆柱数据信息
   * @params meshheight  圆柱的高度
   */
  CysGeometry2 = (
    position,
    radius,
    topHeight,
    clolor,
    data,
    meshheight = 0
  ) => {
    // 裁剪
    // const clippingPlane = new THREE.Plane(;
    // let position = customCoords.lngLatToCoord(positions);
    // const geometry = new THREE.CylinderGeometry(radius, radius, topHeight, 320);
    // const geometry2 = new THREE.CylinderGeometry(radius -100, radius-100, topHeight, 320);
    var geometry = new THREE.CircleGeometry(2000, 61);
    geometry.vertices.shift()

    const material = new THREE.LineBasicMaterial({
      // color: 0x2defff,
      color: clolor,
      linewidth: 100
      // transparent: true,
      // opacity: 0.4,
      // side: THREE.DoubleSide, //双面可见
      // depthWrite: false, //深度监测关闭
      // clippingPlanes: [position[0], position[1], meshheight]
    });


    const cylinder = new THREE.Line(geometry, material);
    cylinder.rotation.x = Math.PI / 2;
    cylinder.position.set(position[0], position[1], meshheight);
    let pointLight = new THREE.PointLight(0xffffff, 1, radius);
    pointLight.position.set(position[0], position[1], 4000);
    // scene.add(pointLight);
    cylinder.typeName = "kongyu";
    cylinder.typedata = data;
    scene.add(cylinder);
    if (this.airspacePolygon[data.airTypeId])
      this.airspacePolygon[data.airTypeId].push(cylinder);
    else this.airspacePolygon[data.airTypeId] = [cylinder];
    return cylinder;
  };


  // CysGeometry2 = (
  //     positions,
  //     radius,
  //     topHeight,
  //     clolor,
  //     data,
  //     meshheight = 0
  // ) => {
  //   console.log(positions)
  //   // 创建一个 Circle 对象
  //   var circleShape = new THREE.Circle(new THREE.Vector2(0, 0), 1, 32);
  //
  //   // 创建一个 Geometry 对象，并使用 Circle 创建出顶点
  //   var circleGeometry = new THREE.BufferGeometry().setFromPoints(circleShape.getPoints(32));
  //
  //   // 创建一个 LineLoop 对象，并将 Geometry 添加到其中
  //   var circleLine = new THREE.LineLoop(circleGeometry, new THREE.LineBasicMaterial({color: 0xff0000}));
  //
  //   // 将 LineLoop 添加到场景中
  //   scene.add(circleLine);
  // }
  addWall(path, colorType) {
    // const material = createOpacityWallMat({ height: 15, speed: 5 })
    // 防御圈墙体材质
    if (wallMat) {
      wallMat = null;
    }
    if (wallMesh) {
      wallMesh = null;
    }
    wallMat = this.createFlowWallMat({ colorType });
    // 防御圈墙体
    wallMesh = this.creatWallByPath({
      path,
      material: wallMat,
      height: 1000,
      expand: true,
    });
    // wallMesh.scene.position.z = 200
    // wallMesh.layers.enable(1)
    // 添加动画数组
    if (wallMesh) {
      animationList.push(wallMesh);
    }
    scene.add(wallMesh);
  }

  /**
   * 创建流体墙体材质
   * option =>
   * params bgUrl flowUrl
   * **/
  createFlowWallMat({ bgUrl, flowUrl, colorType = 3 }) {
    // 顶点着色器
    const vertexShader = `
          varying vec2 vUv;
          varying vec3 fNormal;
          varying vec3 vPosition;
          void main(){
                  vUv = uv;
                  vPosition = position;
                  vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
                  gl_Position = projectionMatrix * mvPosition;
          }
      `;
    // 片元着色器
    const fragmentShader = `
          uniform float time;
          varying vec2 vUv;
          uniform sampler2D flowTexture;
          uniform sampler2D bgTexture;
          void main( void ) {
              vec2 position = vUv;
              vec4 colora = texture2D( flowTexture, vec2( vUv.x, fract(vUv.y - time )));
              vec4 colorb = texture2D( bgTexture , position.xy);
              gl_FragColor = colorb + colorb * colora;
          }
      `;
    // 背景图
    const bgTexture = new THREE.TextureLoader().load(
      bgUrl || import.meta.env.VITE_BASE_PUBLICPATH + `/img/cockpit/defenseRedLine${colorType}.png`
    );
    // 动画背景
    const flowTexture = new THREE.TextureLoader().load(
      flowUrl || import.meta.env.VITE_BASE_PUBLICPATH + "/img/cockpit/defenseAnimateVerticle.png"
      // 'https://model.3dmomoda.com/models/da5e99c0be934db7a42208d5d466fd33/0/gltf/F3E2E977BDB335778301D9A1FA4A4415.png'
      // "https://model.3dmomoda.com/models/47007127aaf1489fb54fa816a15551cd/0/gltf/116802027AC38C3EFC940622BC1632BA.jpg"
    );
    // 允许平铺
    flowTexture.wrapS = THREE.RepeatWrapping;
    return new THREE.ShaderMaterial({
      uniforms: {
        time: {
          value: 0,
        },
        flowTexture: {
          value: flowTexture,
        },
        bgTexture: {
          value: bgTexture,
        },
      },
      transparent: true,
      depthWrite: false,
      side: THREE.DoubleSide,
      vertexShader: vertexShader,
      fragmentShader: fragmentShader,
    });
  }

  /**
   * 通过path构建墙体
   * option =>
   * params height path material expand(是否需要扩展路径)
   * **/
  creatWallByPath({ height = 2000, path = [], material, expand = true }) {
    let verticesByTwo = null;
    // 1.处理路径数据  每两个顶点为为一组
    if (expand) {
      // 1.1向y方向拉伸顶点
      verticesByTwo = path.reduce((arr, [x, y, z]) => {
        return arr.concat([
          [
            [x, y, z],
            [x, y, z + height],
          ],
        ]);
      }, []);
    } else {
      // 1.2 已经处理好路径数据
      verticesByTwo = path;
    }
    // 2.解析需要渲染的四边形 每4个顶点为一组
    const verticesByFour = verticesByTwo.reduce((arr, item, i) => {
      if (i === verticesByTwo.length - 1) {
        return arr;
      }
      return arr.concat([[item, verticesByTwo[i + 1]]]);
    }, []);
    // 3.将四边形面转换为需要渲染的三顶点面
    const verticesByThree = verticesByFour.reduce((arr, item) => {
      const [[point1, point2], [point3, point4]] = item;
      return arr.concat(
        ...point2,
        ...point1,
        ...point4,
        ...point1,
        ...point3,
        ...point4
      );
    }, []);
    const geometry = new THREE.BufferGeometry();
    // 4. 设置position
    const vertices = new Float32Array(verticesByThree);
    // geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
    geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));

    // 5. 设置uv 6个点为一个周期 [0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1]

    // 5.1 以18个顶点为单位分组
    const pointsGroupBy18 = new Array(verticesByThree.length / 3 / 6)
      .fill(0)
      .map((item, i) => {
        return verticesByThree.slice(i * 3 * 6, (i + 1) * 3 * 6);
      });
    // 5.2 按uv周期分组
    const pointsGroupBy63 = pointsGroupBy18.map((item, i) => {
      return new Array(item.length / 3)
        .fill(0)
        .map((it, i) => item.slice(i * 3, (i + 1) * 3));
    });
    // 5.3根据BoundingBox确定uv平铺范围
    geometry.computeBoundingBox();
    const { min, max } = geometry.boundingBox;
    const rangeX = max.x - min.x;
    const uvs = [].concat(
      ...pointsGroupBy63.map((item) => {
        const point0 = item[0];
        const point5 = item[5];
        const distance =
          new THREE.Vector3(...point0).distanceTo(
            new THREE.Vector3(...point5)
          ) /
          (rangeX / 10);
        return [0, 1, 0, 0, distance, 1, 0, 0, distance, 0, distance, 1];
      })
    );
    geometry.setAttribute(
      "uv",
      new THREE.BufferAttribute(new Float32Array(uvs), 2)
    );
    // 更新法线
    // geometry.computeVertexNormals();
    const meshMat =
      material ||
      new THREE.MeshBasicMaterial({
        color: 0x00ffff,
        side: THREE.DoubleSide,
        transparent: true,
        depthWrite: false,
        alphaMap: new THREE.TextureLoader().load(""), // 不透明图片
      });
    return new THREE.Mesh(geometry, meshMat);
  }
  /**
   * 清除墙体
   * **/
  removewall() {
    // if (companyLayers.length > 0) {
    //   companyLayers.forEach((item) => {
    //     aMap.remove(item);
    //   });
    //   companyLayers = [];
    // }
    if (wallMesh) {
      wallMesh = null;
    }
    if (animationList.length > 0) {
      animationList.forEach((item) => {
        scene.remove(item);
      });
      animationList = [];
    }
  }
  /**
   * @description : 回显几何体
   */
  polygonGeometry = (polygon, depth, clolor, data) => {
    const province = new THREE.Object3D();
    //纹理
    const shape = new THREE.Shape();
    //材质
    const lineMaterial = new THREE.LineBasicMaterial({ color: clolor });
    //创建一个立方体几何对象Geometry
    const linGeometry = new THREE.BufferGeometry();
    const pointsArray = [];
    let linelist = [];
    for (let i = 0; i < polygon.length; i++) {
      //projection 映射方法
      // const [x, y] = projection(polygon[i])
      //转成three.js的坐标
      const [x, y] = customCoords.lngLatToCoord(polygon[i]);
      if (i === 0) {
        //起点
        shape.moveTo(x, y);
        // shape.moveTo(x, -y);
      }
      //下个点的位置
      shape.lineTo(x, y);
      // shape.lineTo(x, -y);
      //顶点坐标添加到geometry对象
      pointsArray.push(new THREE.Vector3(x, y, 2.01));
      // pointsArray.push(new THREE.Vector3(x, -y, 2.01));
      // linGeometry.vertices.push(new THREE.Vector3(x, -y, 2.01))
      linelist.push([
        new THREE.Vector3(x, y, 0),
        new THREE.Vector3(x, y, depth),
      ]);
    }
    linelist.forEach((item) => {
      const linGeometry2 = new THREE.BufferGeometry();
      linGeometry2.setFromPoints(item);
      const line3 = new THREE.Line(linGeometry2, lineMaterial);
      province.add(line3);
    });
    // 放入多个点
    linGeometry.setFromPoints(pointsArray);
    const extrudeSettings = {
      depth: depth, //厚度
      bevelEnabled: false, //表示拉伸是否产生倒角
    };
    //拉伸 第二个参数是拉伸参数，数据类型是对象， 属性amount表示拉伸长度
    const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
    //基础网格材质，不受光照影响的材质 设置材质效果
    //根据数值来判断颜色
    const material = new THREE.MeshToonMaterial({
      // color: handlerColor(elem.properties.timeValue),
      color: clolor,
      transparent: true,
      opacity: 0.2,
      // side: THREE.DoubleSide, //双面可见
      depthWrite: false, //深度监测关闭
    });
    //网格模型对象Mesh
    const mesh = new THREE.Mesh(geometry, material);
    // mesh.position.set(0, height, 0);
    //线条模型对象
    const line = new THREE.Line(linGeometry, lineMaterial);
    //偏移一条高度的线
    const topline = new THREE.Line(linGeometry, lineMaterial).translateZ(depth);
    province.add(mesh);
    province.add(line);
    province.add(topline);

    // 将geojson的properties放到模型中，后面会用到
    // province.properties = elem.properties;
    // province.rotation.x = Math.PI;
    // mesh.typeName = "kongyu";
    // mesh.typedata = data;
    scene.add(province);
    if (this.airspacePolygon[data.airTypeId])
      this.airspacePolygon[data.airTypeId].push(province);
    else this.airspacePolygon[data.airTypeId] = [province];
  };

  polygonGeometry2 = (polygon, depth, clolor, data) => {
    let noflylist = [];
    // 创建一个 Shape 对象
    var shape = new THREE.Shape();
    for (let i = 0; i < polygon.length; i++) {
      //projection 映射方法
      // const [x, y] = projection(polygon[i])
      //转成three.js的坐标
      const [x, y] = customCoords.lngLatToCoord(polygon[i]);
      if (i === 0) {
        //起点
        shape.moveTo(x, y);
        // shape.moveTo(x, -y);
      }
      //下个点的位置
      shape.lineTo(x, y);

      //添加墙体数据
      noflylist.push([x, y, 0]);
    }
    //创建流光墙 =====现在不需要了
    // this.addWall(noflylist, 3);

    // 创建一个 Geometry 对象，并使用 Shape 创建出顶点
    var squareGeometry = new THREE.ShapeGeometry(shape);

    // 创建一个 LineLoop 对象，并将 Geometry 添加到其中
    var squareLine = new THREE.LineLoop(
      squareGeometry,
      new THREE.LineBasicMaterial({
        color: clolor,
        linewidth: 20, // 线的宽度
      })
    );

    // 将 LineLoop 添加到场景中
    scene.add(squareLine);
    if (this.airspacePolygon[data.airTypeId])
      this.airspacePolygon[data.airTypeId].push(squareLine);
    else this.airspacePolygon[data.airTypeId] = [squareLine];
  };
  /**
   * @description : 清除单个添加的东西
   * @params some 创建的东西
   */
  remove(some) {
    scene.remove(some);
  }

  /**
   * @description : 清除几何体
   */
  removeCysGeometry = (airspaces) => {
    if (airspaces && this.airspacePolygon[airspaces]) {
      this.airspacePolygon[airspaces].forEach((item) => {
        scene.remove(item);
      });
      this.airspacePolygon[airspaces] = [];
    }
  };


  /**
   * @description : 无人机轨迹
   * @params data 无人机轨迹信息
   * */
  aircraftTrack = (data) => {
    let list = [];
    let flyHandPoint = null;
    let flyHandLine = null;
    data.position.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线

    // 如果飞手坐标存在则绘制飞手航线
    if (data.driverIcon) {
      flyHandPoint = this.iconSprite(
        data.dirverPosition,
        data.driverIcon,
        data,
        null,
        0.025,
        0.03
      );
      flyHandLine = this.dashedline(data.flyHandToAircraft);
    }
    routeLine = new THREE.CatmullRomCurve3(list);
    routeLine.curveType = "centripetal"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine.tension = 0; //设置线的张力，0为无弧度折线
    routeLine.closed = false; // 曲线是否闭合

    return { routeLine, flyHandPoint, flyHandLine };
  };

  /**
   * @description : 演示轨迹
   * */
  exampleTrack = (trackList, EMC) => {
    let list = [];
    trackList.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线
    routeLine = new THREE.CatmullRomCurve3(list);
    routeLine.curveType = "catmullrom"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine.tension = 0; //设置线的张力，0为无弧度折线
    routeLine.closed = false; // 曲线是否闭合
    if (EMC) {
      this.diffusionwave(1.5, 0xFF9512, EMC);
      // let arr = customCoords.lngLatsToCoords([EMC[0], EMC[1]]).flat();
      // arr.push(EMC[2]);
      // let [x, y, z] = arr;
      // corrugatedCircle.position.set(x, y, z);
    }
    return routeLine;
  };

  /**
   * @description : 气象演示轨迹
   * */
  meteorologicalShow = (trackList, EMC) => {
    this.aMap.setZoomAndCenter(14.6, [120.217446, 30.208109]);
    this.aMap.setRotation(10);
    this.aMap.setPitch(65);
    let list = [];
    trackList.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线
    routeLine = new THREE.CatmullRomCurve3(list);
    routeLine.curveType = "catmullrom"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine.tension = 0; //设置线的张力，0为无弧度折线
    routeLine.closed = false; // 曲线是否闭合
    if (EMC) {
      this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/yuNew1.png", 200, 0, EMC, 800, true); //第一组雪花从第0秒播放
      this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/yuNew2.png", 200, 500, EMC, 800, true); //第二组雪花从0.5秒播放，做一个雪花的视差效果
      this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/yuNew3.png", 200, 1000, EMC, 800, true); //第三组雪花从1秒播放，以下以此类推
      this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/yuNew4.png", 200, 1500, EMC, 800, true);
      this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/yuNew5.png", 200, 2000, EMC, 800, true);
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/snow1.png", 100, 0, EMC); //第一组雪花从第0秒播放
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/snow2.png", 100, 500, EMC); //第二组雪花从0.5秒播放，做一个雪花的视差效果
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/snow3.png", 100, 1000, EMC); //第三组雪花从1秒播放，以下以此类推
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/snow4.png", 100, 1500, EMC);
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/snow5.png", 100, 2000, EMC);
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind1.png", 100, 0, EMC); //第一组雪花从第0秒播放
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind2.png", 100, 500, EMC); //第二组雪花从0.5秒播放，做一个雪花的视差效果
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind3.png", 100, 1000, EMC); //第三组雪花从1秒播放，以下以此类推
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind4.png", 100, 1500, EMC);
      // this.atmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind5.png", 100, 2000, EMC);
    }
    return routeLine;
  };

  atmosphere = (
    texturePath,
    count,
    seek,
    EMC,
    size = 40,
    transparent = false
  ) => {
    let texture = new THREE.TextureLoader().load(texturePath);
    // atmosphereGeometry = new THREE.Geometry();
    atmosphereGeometry = new THREE.Geometry();
    for (var i = 0; i < count; i++) {
      var particle = new THREE.Vector3(
        Math.random() * 2000 - 1000, // x 坐标范围 (-5, 5)
        Math.random() * 2000 - 1000, // y 坐标范围 (-5, 5)
        Math.random() * 1000 - 1000 // z 坐标范围 (-5, 5)
      );
      atmosphereGeometry.vertices.push(particle);
    }
    // 创建粒子系统的材质
    var material = new THREE.PointsMaterial({
      map: texture,
      size: size,
      transparent: transparent, //使用背景透明的png贴图，注意开启透明计算
      // color: 0xffffff,
      // size: 50,
    });

    // 创建粒子系统对象
    particles = new THREE.Points(atmosphereGeometry, material);
    // 设置粒子系统的位置
    let arr = customCoords.lngLatsToCoords([EMC[0], EMC[1]]).flat();
    arr.push(EMC[2]);
    let [x, y, z] = arr;
    particles.position.set(x, y, z);

    for (var i = 0; i < atmosphereGeometry.vertices.length; i++) {
      var particle = atmosphereGeometry.vertices[i];
      // 使粒子下降
      particle.y -= 0.1;
      if (particle.y < -5) {
        particle.y = 5; // 重置粒子的位置，使其重新从顶部开始下降
      }
    }
    atmosphereGeometry.verticesNeedUpdate = true; // 更新几何体的顶点位置


    let a = anime({
      direction: "normal",
      targets: particles.position.set(x, y, z),
      z: [1000, 0], //让points.position的y值,从5变化到-5     //这个属性改变可以改变例子效果的方向
      // x: [1000, -500], //让points.position的y值,从5变化到-5     //这个属性改变可以改变例子效果的方向
      duration: 1500, //动画时间3秒
      easing: "linear", //线性动画
      // ry: Math.PI * 0.5,
      rx: Math.PI * 0.5,
      loop: true, //动画无限循环
      autoplay: false, //关闭自动播放动画
    });
    a.seek(seek); //改变动画的播放时间,从第几秒开始,用于做一个动画时间差
    a.play(); //改变了起始播放时间后再播放动画
    particleslist.push(particles);
    scene.add(particles); // 将粒子系统添加到场景中
  };

  /**
   * @description : 风演示轨迹
   * */
  windShow = (trackList, EMC) => {
    this.aMap.setZoomAndCenter(14, [120.217446, 30.208109]);
    this.aMap.setRotation(10);
    this.aMap.setPitch(65);
    let list = [];
    trackList.map((item) => {
      let point = customCoords.lngLatsToCoords(item)[0];
      list.push(new THREE.Vector3(point[0], point[1], item[2]));
    }); // 直接绑定方块的position以便后续用方块调整曲线
    routeLine = new THREE.CatmullRomCurve3(list);
    routeLine.curveType = "catmullrom"; // 曲线类型 可能的值为centripetal、chordal和catmullrom。
    routeLine.tension = 0; //设置线的张力，0为无弧度折线
    routeLine.closed = false; // 曲线是否闭合
    if (EMC) {
      // this.windatmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind1.png", 70, 0, EMC, 800, true); //第一组雪花从第0秒播放
      // this.windatmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind2.png", 70, 500, EMC, 800, true); //第二组雪花从0.5秒播放，做一个雪花的视差效果
      // this.windatmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind3.png", 70, 1000, EMC, 800, true); //第三组雪花从1秒播放，以下以此类推
      // this.windatmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind4.png", 70, 1500, EMC, 800, true);
      // this.windatmosphere(import.meta.env.VITE_BASE_PUBLICPATH + "/img/weather/wind5.png", 70, 2000, EMC, 600, true);
    }
    return routeLine;
  };

  windatmosphere = (
    texturePath,
    count,
    seek,
    EMC,
    size = 40,
    transparent = false
  ) => {
    let texture = new THREE.TextureLoader().load(texturePath);
    atmosphereGeometry = new THREE.Geometry();
    for (var i = 0; i < count; i++) {
      var particle = new THREE.Vector3(
        Math.random() * 2000 - 500, // x 坐标范围 (-5, 5)
        Math.random() * 2000 - 500, // y 坐标范围 (-5, 5)
        Math.random() * 1000 - 500 // z 坐标范围 (-5, 5)
      );
      atmosphereGeometry.vertices.push(particle);
    }
    // 创建粒子系统的材质
    var material = new THREE.PointsMaterial({
      map: texture,
      size: size,
      transparent: transparent, //使用背景透明的png贴图，注意开启透明计算
      // opacity: 1,
      // color: 0xffffff,
      // size: 50,
    });

    // 创建粒子系统对象
    particles = new THREE.Points(atmosphereGeometry, material);
    // 设置粒子系统的位置
    let arr = customCoords.lngLatsToCoords([EMC[0], EMC[1]]).flat();
    arr.push(EMC[2]);
    let [x, y, z] = arr;
    particles.position.set(x, y, z);

    for (var i = 0; i < atmosphereGeometry.vertices.length; i++) {
      var particle = atmosphereGeometry.vertices[i];
      // 使粒子下降
      particle.y -= 0.1;
      if (particle.y < -5) {
        particle.y = 5; // 重置粒子的位置，使其重新从顶部开始下降
      }
    }
    atmosphereGeometry.verticesNeedUpdate = true; // 更新几何体的顶点位置

    let a = anime({
      targets: particles.position.set(x, y, z),
      z: [500, 0], //让points.position的y值,从5变化到-5     //这个属性改变可以改变例子效果的方向
      // x: [500, 0],
      duration: 3000, //动画时间3秒
      easing: "linear", //线性动画
      ry: Math.PI * 0.5,
      loop: true, //动画无限循环
      autoplay: false, //关闭自动播放动画
    });
    a.seek(seek); //改变动画的播放时间,从第几秒开始,用于做一个动画时间差
    a.play(); //改变了起始播放时间后再播放动画
    particleslist.push(particles);
    scene.add(particles); // 将粒子系统添加到场景中
  };
  /**
   * @description : 清除粒子效果
   * */
  clearparticles() {
    if (particleslist.length > 0) {
      particleslist.forEach((item) => {
        scene.remove(item);
      });
    }
  }

  clearAtmosphere = () => {
    if (atmosphereGeometry) {
      atmosphereGeometry.dispose();
      scene.remove(particles);
      particles.visible = false;
    }
  };
}
export default Threesence;
